Versatz der Mantelfläche um nach außen → Gefäßwand
Schritt 1: Querschnitt als Spline
import build123d as bd
from ocp_vscode import show
defmake_section(phi_val, n=25):
theta = np.linspace(0, 2*np.pi, n, endpoint=False)
r = R(theta, phi_val); z = Z(theta, phi_val)
x, y = r * np.cos(phi_val), r * np.sin(phi_val)
points = [bd.Vertex(1e3 * xi, 1e3 * yi, 1e3 * zi) for xi, yi, zi inzip(x, y, z)]
spline = bd.Spline(*points, periodic=True)
return points, spline
phi_values = np.linspace(0, 2*np.pi/10, 10)
show([make_section(phi) for phi in phi_values])
periodic=True → geschlossene Kurve ohne Knick am Anfangspunkt
Rückgabe: Edge (ein einzelner Spline-Bogen)
Schritt 2: Loft einer halben Feldperiode
W7-X hat 5-fache toroidale Symmetrie mit Spiegelsymmetrie pro Periode
→ Halbe Periode
phi_values = np.linspace(0, 2*np.pi/10, 20)
sections = [bd.Wire([make_section(phi)[1]]) for phi in phi_values]
plasma = bd.Solid.make_loft(sections)
show(plasma)
sections: Liste von Wire-Objekten (hier: je ein Spline)
make_loft → erzeugt eine durch die sections verlaufende Fläche (Loft)
[e.geom_type for e in plasma.faces()] → [BSPLINE, PLANE, PLANE]
Schritt 3: Gefäßwand mit offset_3d
# Planare Deckelflächen als "Öffnungen" → offset_3d erzeugt eine Schale
caps = plasma.faces().filter_by(bd.GeomType.PLANE)
wall = plasma.offset_3d(caps, 200)
# Nur die äußere Versatzfläche behalten
vessel_face = wall.faces().filter_by(bd.GeomType.OFFSET)
show(plasma, vessel_face, names=["Plasmaoberfläche", "Gefäßwand"])
offset_3d(openings, amount) → hält die openings-Flächen offen, versetzt alle anderen um amount
[e.geom_type for e in wall.faces()] → [BSPLINE, PLANE, OFFSET, PLANE]
.filter_by(GeomType.OFFSET) → selektiert die neu entstandene Außenfläche
Freiformkurven
Motivation: Grenzen analytischer Kurven
Wie beschreibt man eine freie Kurve mathematisch?
Analytische Kurven aus Teil 1 (Linie, Kreis, Ellipse, Kegelschnitte) haben eine feste Form – ihre Gleichung bestimmt den Kurvenverlauf vollständig, freie Formgebung ist nicht möglich.
Das W7-X-Beispiel vom Beginn dieser Vorlesung illustriert das: Der Querschnitt des Plasmabehälters lässt sich durch keinen analytischen Kurventyp ausdrücken.
→ Wir brauchen Freiformkurven: flexibel formbar, lokal steuerbar, für beliebige Geometrie geeignet.
Wiederholung: Parametrische Kurven
Eine parametrische Kurve bildet einen Parameter auf einen Punkt im Raum ab:
Analytische Kurve
Parametrisierung
Linie
Kreis (Radius )
Ellipse
Vorteile der Parameterdarstellung:
Punkte, Tangenten, Krümmung durch einfache Ableitungen ,
Einfach zu verkürzen und einen Punkt auf der Kurve zu finden
Warum Polynome?
Eine Kurve ist eine Funktion – aber welche Funktion wählt man?
→ Alle Freiformkurven in CAD (Bézier, B-Spline, NURBS) basieren auf stückweisen Polynomen niedrigen Grades.
Kurven in Potenzbasis
Der naheliegende Ansatz: Koordinaten als Polynome in ,
Probleme der Potenzbasis:
Kein geometrischer Bezug: Die Koeffizienten haben keine anschauliche Bedeutung – man kann den Kurvenverlauf nicht aus ihnen ablesen
Numerische Empfindlichkeit: Bei hohen Graden reagiert die Kurvenform sehr sensibel auf kleine Änderungen einzelner Koeffizienten
Schlechte Interaktivität: Um eine Kurve zu ändern, muss man ein Gleichungssystem lösen
→ Gesucht: eine Basis, deren Parameter direkt geometrische Bedeutung haben.
Pierre Bézier
Anfang der 1960er Jahre bei Renault:
Ziel: Karosserie-Design am Computer
1962 publiziert
CAD-System: UNISURF (1968)
Idee: Kontrollpunkte, die die Kurve anziehen – geometrisch intuitiv, numerisch stabil.
Bézier-Kurven: Formel
: Kontrollpunkte (bilden das Kontrollpolygon)
: Bernstein-Basisfunktionen – nicht-negativ,
Grad = Anzahl Kontrollpunkte
Geometrische Interpretation: ist stets eine Konvexkombination der Kontrollpunkte → die Kurve liegt immer innerhalb der konvexen Hülle des Kontrollpolygons.
Bézier-Kurven: Grade 1, 2 und 3
Grad
Kontrollpunkte
Form
gerade Strecke
Parabel
kubische Kurve
Eigenschaften:
Kurve läuft durch und
Tangente in : Richtung
Kurve liegt in der konvexen Hülle der Kontrollpunkte
Scharfe Kante: lokale Vielfachheit → gezielter Knick in der Kurve
Bézier-Extraktion: Vielfachheit an allen inneren Knoten → stückweise Bézier-Darstellung
NURBS: Warum?
Kann ein B-Spline einen perfekten Kreis darstellen?
Antwort: Nein – B-Splines sind stückweise Polynome, Kreise sind trigonometrisch. Ein B-Spline kann einen Kreis nur annähern, nie exakt darstellen.
Das zeigt: B-Splines sind nicht allgemein genug für alle Kurvenformen.
Hinweis: OCCT speichert Kreise intern trotzdem als CIRCLE (analytisch, exakt) – nicht als B-Spline. Aber: CAD-Systeme, die intern nur eine Kurvenart verwenden, brauchen eine Darstellung, die auch Kreise exakt abdeckt.
→ Lösung: Gewichte hinzufügen → NURBS kann Kreise, Kegelschnitte und Freiformkurven in einem Format darstellen.
Warum kein Polynom für den Kreis?
Ein B-Spline ist stückweise polynomial:
Sind , Polynome vom Grad , so ist ein Polynom vom Grad .
Dieses kann nur dann für alle konstant gleich sein, wenn alle nicht-konstanten Terme verschwinden – d. h. und wären konstant. Widerspruch.
Ein B-Spline kann einen Kreis nur annähern, niemals exakt darstellen.
NURBS: rationale Parametrisierung des Kreises
Rationale Funktionen (Quotient zweier Polynome) umgehen dieses Problem:
Viertelkreis als quadratische NURBS (exakt):
Kontrollpunkt
Gewicht
Das reduzierte Gewicht „zieht" die Kurve vom Kontrollpunkt weg – genau so, dass der Kreisbogen entsteht.
NURBS – Non-Uniform Rational B-Splines
Erweiterung des B-Spline um Gewichte:
für alle → normaler B-Spline (Spezialfall)
Größeres → Kurve nähert sich stärker dem Kontrollpunkt
Entscheidender Vorteil:
B-Spline kann Kreise und Kegelschnitte nur annähern.
NURBS stellt sie exakt dar.
NURBS: die universelle Darstellung
Linie / Kreis ⊂ Bézier ⊂ B-Spline ⊂ NURBS
Alle analytischen Kurven sind Spezialfälle von NURBS – daher ist NURBS der einheitliche Standard in industriellen CAD-Systemen (CATIA, SolidWorks, NX, OCCT).
geom_type in OCCT
Bedeutung
LINE, CIRCLE, ELLIPSE
analytisch gespeichert (exakt)
BSPLINE
NURBS-Kurve (Freiformkurve oder konvertierte Analytik)
Beim Import aus STEP: Freiformkurven erscheinen als BSPLINE, auch wenn sie ursprünglich Kreise waren – je nach exportierendem System.
Übung: Spline vs. Polyline
Datei: praktikum_stetigkeit.py – Aufgabe 1
Erzeuge dieselben 5 Punkte einmal mit Spline und einmal mit Polyline. Gib geom_type aller Kanten aus:
punkte = [(0,0,0),(10,15,0),(25,5,0),(40,20,0),(50,0,0)]
with bd.BuildLine() as bl_spline:
bd.Spline(*punkte)
with bd.BuildLine() as bl_poly:
bd.Polyline(*punkte)
print([e.geom_type for e in bl_spline.edges()])
print([e.geom_type for e in bl_poly.edges()])
Füge danach tangents=[(1,0,0),(0,-1,0)] hinzu – ändert sich der geom_type?
Übung: fillet als Flächenerzeuger
Datei: praktikum_stetigkeit.py – Aufgabe 2
box = bd.Box(50, 30, 20)
box_f = bd.fillet(box.edges(), 3)
print(set(f.geom_type for f in box.faces()))
print(set(f.geom_type for f in box_f.faces()))
Welche geom_type-Werte erscheinen neu? Warum auch SPHERE?
Flächen
Parametrische Flächen: Wiederholung
Jede Fläche ist eine Funktion von zwei Parametern und :
Jede Face in einem B-Rep-Modell trägt eine solche parametrische Fläche.
Analytische Flächen
Exakt durch eine geschlossene Formel beschreibbar:
Typ
Charakteristik
geom_type
build123d
Ebene
konstante Normale
PLANE
Box, Rectangle
Zylinder
CYLINDER
Cylinder
Kegel
wie Zylinder,
CONE
Cone
Kugel
SPHERE
Sphere
Torus
Kreisring um Achse
TORUS
Torus
Für Standardkörper reichen analytische Flächen vollständig aus.
Sweep-Flächen
Entstehen durch Bewegung eines Profils entlang einer Leitkurve:
Typ
Beispiel
geom_type (Kreis-Profil)
geom_type (Freiform)
Extrusion
Wandfläche
CYLINDER
BSPLINE
Rotation
Kegelfläche
SPHERE / TORUS
BSPLINE
Sweep
Rohr, Schiene
CYLINDER
BSPLINE
Loft
Tragflügel, Rumpf
BSPLINE
BSPLINE
Das Eingangsprofil bestimmt die Komplexität der Ausgabefläche.
NURBS-Flächen
Verallgemeinerung der NURBS-Kurve auf zwei Parameter:
Kontrollpunktnetz: 2D-Gitter statt 1D-Liste
Spezialfall : Nenner = 1 (da ) → B-Spline-Fläche
In OCCT: geom_type == 'BSPLINE' gilt für beide Fälle – B-Spline und NURBS sind dieselbe Klasse
Dieselben Bedingungen wie bei Kurven, jetzt für aneinanderstoßende Flächen:
Grad
Bedingung
Sichtbar als
kein Spalt
scharfe Kante
Normalenvektoren stetig (gleiche Tangentenebene)
Kante verschwindet im Licht
Krümmung stetig
Reflexion läuft nahtlos durch
In build123d:
fillet(edges, radius) → an der Kante
Verbindungsflächen zwischen Loft-Profilen → je nach Einstellung bis
W7-X: Die BSPLINE-Mantelfläche und die OFFSET-Gefäßwand stoßen an den Deckeln auf PLANE-Flächen – dort ist nur garantiert (scharfe Kante).
Übung: Loft → NURBS-Fläche
Datei: praktikum_stetigkeit.py – Aufgabe 3
Lofte von einem Kreis (unten) auf ein Rechteck (oben):
kreis = bd.Wire([bd.Edge.make_circle(10)])
# ... Rechteck in 40 mm Höhe ...
loft = bd.Solid.make_loft([kreis, rechteck])
print(set(f.geom_type for f in loft.faces()))